package com.yw.atp.service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.yw.atp.model.IDEntity;
import com.yw.atp.model.Reply;
import com.yw.atp.model.Staff;

/**
 * 数据库基本服务
 */
@Repository
public class PersistenceService {

    @PersistenceContext
    private EntityManager em;

    /**
     * 仅仅预留给service包里面的其它服务使用。
     * @return EntityManager
     */
    protected EntityManager getEntityManager() {
        return em;
    }

    /**
     * 根据主键查找一个对象。
     * @param clz 类型
     * @param key 主键
     * @return 对象
     */
    @Transactional
    public <T extends IDEntity> T find(Class<T> clz, Object key) {
        return em.find(clz, key);
    }

    /**
     * 找到某一类型的所有对象
     * @param clz 类型
     * @param options 其它参数[可以是0，1，2个参数]。 第一个表示offset，第二个表示返回的最大记录数。
     * @return 对象列表
     */
    @Transactional
    public <T extends IDEntity> List<T> findAll(Class<T> clz, int... options) {
        Query query = em.createQuery("select o FROM " + clz.getName() + " o where o.status!='1' order by o.id desc");
        if (options.length > 0) {
            query.setFirstResult(options[0]);
        }
        if (options.length > 1) {
            query.setMaxResults(options[1]);
        }
        return (List<T>) query.getResultList();
    }
    
    @Transactional
    public <T extends IDEntity> List<T> execHql(String hql,Map<String,Object> params) {
        Query query = em.createQuery(hql);
        Set<String> keys = params.keySet();
        for(String key:keys){
        	query.setParameter(key,params.get(key));
		}
        return (List<T>) query.getResultList();
    }
    
    /**
     * 删除一个对象。[要求在一个事务中执行]
     * @param objects 对象
     */
    @Transactional
    public <T extends IDEntity> void remove(T... objects) {
        for(T obj : objects){
        	em.remove(em.merge(obj));
        }
    }
    
    public boolean isExsist(String className,int id){
		StringBuffer sb = new StringBuffer();
		sb.append("select o FROM "+className+" o where o.id = "+id);	
		Query query = em.createQuery(sb.toString());
		return query.getResultList().size()>0?true:false;
	}
    
    @Transactional
    public void del(String className,String ids){
    	Query query = em.createQuery("delete from " + className + " o where o.id in ("+ids+")");
    	query.getSingleResult();
    }
    
    @Transactional
    public void remove(String className,String ids){
    	Query query = em.createQuery("update " + className + " o set o.status = '1' , o.updateAt = :upDate where o.id in ("+ids+")");
    	query.setParameter("upDate",new Date());
    	query.executeUpdate();
    }
    
    @Transactional
    public void updateStatus(String className,String id,String status){
    	Query query = em.createQuery("update " + className + " o set o.status = '"+status+"' , o.updateAt = :upDate where o.id in ("+id+")");
    	query.setParameter("upDate",new Date());
    	query.executeUpdate();
    }
    
    /**
     * 保存一个对象。[要求在一个事务中执行] </br>
     * 如果 obj.getId()==null ，则表示插入新对象，否则将会执行update。
     * @param objs 对象
     */
    @Transactional
    public <T extends IDEntity> void save(T... objs) {
        for (T obj : objs) {
            if (obj.getId() == null) {
                em.persist(obj);
            } else {
                em.merge(obj);
            }
        }
    }

    /**
     * 从数据库中刷新一个对象。[要求在一个事务中执行] </br>
     * 如果对象已经被临时更改过，所有的变更将会丢失，重新载入数据库中的值。
     * @param objs 对象
     */
    @Transactional
    public <T extends IDEntity> void refresh(T... objs) {
        for(T obj : objs){
            em.refresh(obj);
        }
    }

    /**
     * 根据一个对象，从数据库中来获取相关数据的简便方法。[要求在一个事务中执行] </br>
     * 等同于  find( (Class<T>) obj.getClass(),obj.getId())
     * @param obj 对象
     * @return  对象
     */
    @Transactional
    public <T extends IDEntity> T load(T obj) {
        if (obj == null) {
            throw new RuntimeException("parameter T: obj can not be null.");
        }
        if (obj.getId() == null) {
            throw new RuntimeException("parameter T: obj must be an entity with ID .");
        }
        return em.find((Class<T>) obj.getClass(), obj.getId());
    }
    
    @Transactional
    public void flush(){
        getEntityManager().flush();
    }

    public List<Object> excNativeQuery(String sql){
    	try{
    		Query  q = em.createNativeQuery(sql);
    		return q.getResultList();
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	return null;
    }
}
